package com.apache.poi.word.controller;

import com.apache.poi.word.config.policy.BreakPageRenderPolicy;
import com.apache.poi.word.config.policy.CustomTableRenderPolicy;
import com.apache.poi.word.config.policy.HelloWorldRenderPolicy;
import com.apache.poi.word.domain.vo.word.AddrModel;
import com.apache.poi.word.domain.vo.word.AthletesTotalVO;
import com.apache.poi.word.domain.vo.word.Goods;
import com.apache.poi.word.domain.vo.word.Labor;
import com.apache.poi.word.utils.WordUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.data.*;
import com.deepoove.poi.data.style.BorderStyle;
import com.deepoove.poi.data.style.CellStyle;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.plugin.toc.TOCRenderPolicy;
import com.deepoove.poi.policy.AbstractRenderPolicy;
import com.deepoove.poi.render.RenderContext;
import com.deepoove.poi.render.WhereDelegate;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import org.apache.commons.io.IOUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.*;

/**
 * @Author: HUANG GY.
 * @Date: 2022/2/7 14:10
 * @Description: com.apache.poi.word.controller
 */
@RestController
public class TlController {

    public static Object testBase() throws  Exception {
        Map<String,Object> params = new HashMap<>();
        params.put("title","我的题目");
//        params.put("name", "Sayi");
//        params.put("author", new TextRenderData("000000", "Sayi"));
//        params.put("link", new HyperlinkTextRenderData("website", "http://deepoove.com"));
//        params.put("anchor", new HyperlinkTextRenderData("anchortxt", "anchor:appendix1"));
        InputStream fileInputStream = WordUtil.getFileInputStream("docs\\tl\\template.docx");
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream).render(params);
        template.writeAndClose(new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\tl\\template001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }

    public static Object testTable01() throws  Exception {
        Map<String,Object> params = new HashMap<>();
        BorderStyle border11 = new BorderStyle();
        border11.setType(XWPFTable.XWPFBorderType.NONE);
        params.put("table0", Tables.of(new String[][] {
                new String[] { "00", "01" },
                new String[] { "10", "11" },
                new String[] { "10", "11" }
        }).border(border11).center().create());
        InputStream fileInputStream = WordUtil.getFileInputStream("docs/tl/table.docx");
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream).render(params);
        NiceXWPFDocument doc = template.getXWPFDocument();
        List<XWPFTable> tables = doc.getTables();
        XWPFTable table = tables.get(0);
//        table.setInsideHBorder( XWPFTable.XWPFBorderType.DOUBLE, 4, 0, "FF0000");

        //https://www.daicuo.cc/biji/2312699
        CTTblPr tblpro = table.getCTTbl().getTblPr();
        CTTblBorders borders = tblpro.addNewTblBorders();
        borders.addNewBottom().setVal(STBorder.DOUBLE);
//        borders.addNewLeft().setVal(STBorder.DOUBLE);
//        borders.addNewRight().setVal(STBorder.DOUBLE);
        borders.addNewTop().setVal(STBorder.DOUBLE);
//also inner borders
//        borders.addNewInsideH().setVal(STBorder.DOUBLE);
//        borders.addNewInsideV().setVal(STBorder.DOUBLE);

        XWPFTableRow row = table.getRow(0);
        XWPFTableCell cell = row.getCell(1);
        CTTc ctTc = cell.getCTTc();
        CTTcPr tcPr = ctTc.getTcPr();
        CTTcBorders border = tcPr.addNewTcBorders();

        border.addNewBottom().setVal(STBorder.SINGLE);
        border.addNewRight().setVal(STBorder.SINGLE);
        border.addNewLeft().setVal(STBorder.SINGLE);
        border.addNewTop().setVal(STBorder.SINGLE);


        template.writeAndClose(new FileOutputStream("/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/table/table001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }
    public static Object testTable002() throws  Exception {
        InputStream fileInputStream = new FileInputStream("/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/table/破纪录名单.docx");
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream);
        NiceXWPFDocument doc = template.getXWPFDocument();
        List<XWPFTable> tables = doc.getTables();
        XWPFTable table = tables.get(0);
        CTTblPr tblpro = table.getCTTbl().getTblPr();
        CTTblBorders borders = tblpro.addNewTblBorders();
        borders.addNewBottom().setVal(STBorder.DOUBLE);
        borders.addNewLeft().setVal(STBorder.DOUBLE);
        borders.addNewRight().setVal(STBorder.DOUBLE);
        borders.addNewTop().setVal(STBorder.DOUBLE);


        XWPFTableRow row = table.getRow(0);
        XWPFTableCell cell = row.getCell(1);
        CTTc ctTc = cell.getCTTc();
        CTTcPr tcPr = ctTc.getTcPr();
        CTTcBorders border = tcPr.addNewTcBorders();

        border.addNewBottom().setVal(STBorder.SINGLE);
        border.addNewRight().setVal(STBorder.SINGLE);
        border.addNewLeft().setVal(STBorder.SINGLE);
        border.addNewTop().setVal(STBorder.SINGLE);


        template.writeAndClose(new FileOutputStream("/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/table/table001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }

    public static Object testTable02() throws  Exception {
        // 第0行居中且背景为蓝色的表格
        CellStyle cellStyle = new CellStyle();
        CellRenderData cell00 = Cells.of("姓名").create();
        CellRenderData cell01 = Cells.of("学历").create();
        RowRenderData row0 = Rows
                .of()
                .addCell(cell00)
                .addCell(cell01)
                .textColor("FFFFFF")
                .bgColor("4472C4")
                .center()
                .rowAtleastHeight(3D)
                .create();
        RowRenderData row1 = Rows.create("李四", "博士");

        Map<String,Object> params = new HashMap<>();
        params.put("table1", Tables.create(row0, row1));
        InputStream fileInputStream = WordUtil.getFileInputStream("docs\\tl\\table.docx");
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream).render(params);
        template.writeAndClose(new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\tl\\table001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }

    /**
     *  表格循环渲染咯
     * @return
     * @throws Exception
     */
    public static Object testTable03() throws  Exception {
        List<AthletesTotalVO> athletesTotalList = new ArrayList<>();
        AthletesTotalVO vo01 = AthletesTotalVO
                .builder()
                .athletesMNum(10)
                .athletesNum(100)
                .athletesWNum(90)
                .coachMNum(2)
                .coachWNum(1)
                .leaderMNum(1)
                .leaderWNum(3)
                .number(102)
                .number(1)
                .organizationName("福建泉州晋江三创园食堂大队")
                .peopleNum(150)
                .teamMembersNum(30)
                .build();
        AthletesTotalVO vo02 = (AthletesTotalVO) vo01.clone();
        AthletesTotalVO vo03 = (AthletesTotalVO) vo01.clone();
        AthletesTotalVO vo04 = (AthletesTotalVO) vo01.clone();
        AthletesTotalVO vo05 = (AthletesTotalVO) vo01.clone();
        for (int i = 0; i < 10; i++) {
            athletesTotalList.add(vo01);
            athletesTotalList.add(vo02);
            athletesTotalList.add(vo03);
            athletesTotalList.add(vo04);
            athletesTotalList.add(vo05);
        }


        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();

        Configure config = Configure.builder()
                .bind("athletesTotalList", policy).build();
        XWPFTemplate template = XWPFTemplate.compile(WordUtil.getFileInputStream("docs/tl/参赛人数统计.docx"), config).render(
                new HashMap<String, Object>() {{
                    put("athletesTotalList", athletesTotalList);
                }}
        );
        template.writeAndClose(new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\tl\\参赛人数统计001.docx"));
        return "啊哈哈test001";
    }


    /**
     *  动态表格渲染
     * @return
     * @throws Exception
     */
    public static Object list01() throws  Exception {
        Map<String,Object> params = new HashMap<>();
        params.put("list0", Numberings.create("Plug-in grammar",
                "Supports word text, pictures, table...",
                "Not just templates"));
        InputStream fileInputStream = WordUtil.getFileInputStream("docs\\tl\\list.docx");
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream).render(params);
        template.writeAndClose(new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\tl\\list001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }


    /**
     *  list渲染
     * @return
     * @throws Exception
     */
    public static Object sections001() throws  Exception {
        Map<String,Object> params = new HashMap<>();
        params.put("announce", Boolean.FALSE);
        HashMap<String, Object> innerMap1 = new HashMap<>();
        innerMap1.put("name","张三");
        params.put("person", innerMap1);
        HashMap<String, Object> innerMap2 = new HashMap<>();
        List<HashMap<String, Object>> arr = new ArrayList<>();
        arr.add(innerMap1);
        arr.add(innerMap1);
        arr.add(innerMap1);
        innerMap2.put("name", innerMap1);
        params.put("songs", arr);
        InputStream fileInputStream = WordUtil.getFileInputStream("docs\\tl\\sections.docx");
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream).render(params);
        template.writeAndClose(new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\tl\\sections001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }

    /**
     *  list渲染
     * @return
     * @throws Exception
     */
    public static Object subDoc001() throws  Exception {
        Map<String,Object> params = new HashMap<>();
        List<AddrModel> subData = new ArrayList<>();
        subData.add(new AddrModel("Hangzhou,China000"));
        subData.add(new AddrModel("Shanghai,China111"));
        params.put("nested", Includes.ofStream(WordUtil.getFileInputStream("docs/tl/subInner.docx")).setRenderModel(subData).create());
        InputStream fileInputStream = WordUtil.getFileInputStream("docs/tl/subOut.docx");

        ConfigureBuilder builder = Configure.builder();
        builder.bind("addr", new BreakPageRenderPolicy());
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream,builder.build()).render(params);
        template.writeAndClose(new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\tl\\subOut001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }

    public static Object configTest001() throws  Exception {
        Map<String,Object> params = new HashMap<>();
        params.put("title","我的题目");
        ConfigureBuilder builder = Configure.builder();
        builder.buildGramer("${", "}");
        Configure configure = builder.build();
        InputStream fileInputStream = WordUtil.getFileInputStream("docs\\tl\\config.docx");
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream,configure).render(params);
        template.writeAndClose(new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\tl\\config001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }


    public static Object plugin() throws  Exception {
        Map<String,Object> params = new HashMap<>();
        ConfigureBuilder builder = Configure.builder();
        //插件与标签绑定
        builder.bind("report", new CustomTableRenderPolicy()).bind("title", new HelloWorldRenderPolicy());
        InputStream fileInputStream = WordUtil.getFileInputStream("docs\\tl\\plugin.docx");
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream,builder.build()).render(params);
        template.writeAndClose(new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\tl\\plugin001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }


    public static Object pluginComplete() throws  Exception {
        Map<String,Object> params = new HashMap<>();
        params.put("sea", "Hello, world!");
        params.put("sea_img", "D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\bb.jpg");
        params.put("sea_feature", Arrays.asList("面朝大海春暖花开", "今朝有酒今朝醉"));
        params.put("sea_location", Arrays.asList("日落：日落山花红四海", "花海：你想要的都在这里"));
        // where绑定policy
        Configure config = Configure.builder().bind("sea", new AbstractRenderPolicy<String>() {
            @Override
            public void doRender(RenderContext<String> context) throws Exception {
                // anywhere
                XWPFRun where = context.getWhere();
                // anything
                String thing = context.getThing();
                // do 文本
                where.setText(thing, 0);
            }
        }).bind("sea_img", new AbstractRenderPolicy<String>() {
            @Override
            public void doRender(RenderContext<String> context) throws Exception {
                // anywhere delegate
                WhereDelegate where = context.getWhereDelegate();
                // any thing
                String thing = context.getThing();
                // do 图片
                FileInputStream stream = null;
                try {
                    stream = new FileInputStream(thing);
                    where.addPicture(stream, XWPFDocument.PICTURE_TYPE_JPEG, 400, 450);
                } finally {
                    IOUtils.closeQuietly(stream);
                }
                // clear
                clearPlaceholder(context, false);
            }
        }).bind("sea_feature", new AbstractRenderPolicy<List<String>>() {
            @Override
            public void doRender(RenderContext<List<String>> context) throws Exception {
                // anywhere delegate
                WhereDelegate where = context.getWhereDelegate();
                // anything
                List<String> thing = context.getThing();
                // do 列表
                where.renderNumbering(Numberings.of(thing.toArray(new String[] {})).create());
                // clear
                clearPlaceholder(context, true);
            }
        }).build();
        InputStream fileInputStream = WordUtil.getFileInputStream("docs\\tl\\pluginComplete.docx");
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream,config).render(params);
        template.writeAndClose(new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\tl\\pluginComplete001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }


    public static Object toctoc() throws  Exception {
        Map<String,Object> params = new HashMap<>();
        // where绑定policy
        Configure config = Configure.builder().bind("toctoc", new TOCRenderPolicy()).build();
        InputStream fileInputStream = WordUtil.getFileInputStream("docs\\work1\\newDoc.docx");
        XWPFTemplate template = XWPFTemplate.compile(fileInputStream,config).render(params);
        template.writeAndClose(new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\tl\\newDoc001.docx"));
        WordUtil.close(fileInputStream);
        return "啊哈哈test001";
    }


    public static void main(String[] args) throws Exception {
//        testBase() ;
//        testTable03();
//        list01();
//        sections001();
//        subDoc001();
//        configTest001();
//        pluginComplete();
        testTable002();
    }

}
